home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Just Call Me Internet
/
Just Call Me Internet.iso
/
prog
/
atari
/
m2
/
cat3src
/
magic
/
i
/
mintutil.i
< prev
next >
Wrap
Text File
|
1997-10-26
|
7KB
|
238 lines
IMPLEMENTATION MODULE MintUtil;
FROM SYSTEM IMPORT ADR, BYTE, WORD, LONGWORD, ADDRESS, CAST;
(*$R-,S-*)
IMPORT MagicDOS, Mintbind, MagicCookie, MagicStrings, StrConv;
IMPORT MagicSys;
(* Mehrere kleinere MiNT Tricks. Version 2 Karsten Isakovic / Berlin
*
* - Umlenken der Ausgaben eines paralellen Prozesses nach /dev/null
* - Umlenken der Ausgaben eines paralellen Prozesses in eine Pipe
* - Auslesen der Ausgaben aus der Pipe.
*)
(* Version in Megamax Modula 2 von Dirk Steins unter Benutzung
* von Magic von Peter Hellinger
*)
TYPE voidType = RECORD
CASE :CARDINAL OF
1 : b : BYTE|
2 : w : WORD|
3 : l : LONGWORD|
4 : card : CARDINAL|
5 : int : INTEGER|
6 : lcard: LONGCARD|
7 : lint : LONGINT|
8 : char : CHAR|
9 : bset : BITSET|
10: lbset: MagicSys.lBITSET |
11: bool : BOOLEAN; |
12: r : ARRAY [0..3] OF INTEGER|
13: a : ADDRESS;
END
END;
VAR v : voidType;
(*
* Startet einen paralellen Prozess der nach /dev/null ausgibt.
* Liefert den PID des neuen Prozesses.
*)
(*$W-*)
PROCEDURE ExecDevNull(REF name, cmdline, env : ARRAY OF CHAR): INTEGER;
VAR null, i, pid : INTEGER;
old : ARRAY [0..3] OF INTEGER;
BEGIN
FOR i:=0 TO 3 DO
old[i] := MagicDOS.Fdup(i-1); (* Kanle -1 .. 2 duplizieren *)
END(*FOR*);
null := MagicDOS.Fopen("u:\dev\null",{MagicDOS.ReadWrite});
FOR i:= 0 TO 3 DO
v.bool := MagicDOS.Fforce(i-1,null); (* Kanle -1 .. 2auf /dev/null *)
END(*FOR*);
pid := Mintbind.Pfork(); (* Prozess verdoppeln *)
IF (pid = 0)
THEN (* Der neue Kindprozess... *)
FOR i:=0 TO 3 DO
v.int := MagicDOS.Fclose(old[i]); (* Kopien schlieen *)
END(*FOR*);
v.int := MagicDOS.Pexec(200, name, cmdline, env); (* berlagern *)
MagicDOS.Pterm(-1); (* Kommt hier nur an, wenn *)
(* Pexec nicht klappte *)
END(*IF*);
FOR i:= 0 TO 3 DO
v.bool := MagicDOS.Fforce(i-1,old[i]); (* Kanle -1 .. 2 zurcksetzen *)
v.int := MagicDOS.Fclose(old[i]); (* Kopien schlieen *)
END(*FOR*);
v.int := MagicDOS.Fclose(null);
RETURN pid;
END ExecDevNull;
(*
* Startet einen parallelen Prozess der in eine neue Pipe ausgibt.
* Liefert den PID des neuen Prozesses und den Filehandle
* der Pipe in 'pipe'.
*)
PROCEDURE ExecPipe (REF name, cmdline, env : ARRAY OF CHAR; VAR pipe : INTEGER) : INTEGER;
VAR pipename : ARRAY [0..39] OF CHAR;
old : ARRAY [0..3] OF INTEGER;
i, masterfd,
slavefd, pid : INTEGER;
BEGIN
pipe := -1;
i := 0;
LOOP
IF i > 999 THEN EXIT END;
MagicStrings.Assign ('u:\pipe\pty.',pipename);
MagicStrings.Append (StrConv.NumToStr (i,10,3,'0'), pipename);
masterfd := MagicDOS.Fcreate (pipename, {MagicSys.Bit2});
IF masterfd > 0 THEN EXIT END;
INC (i);
END;
IF masterfd < 0 THEN RETURN -1 END;
slavefd := MagicDOS.Fopen (pipename, {MagicDOS.ReadWrite});
IF slavefd < 0
THEN
v.int := MagicDOS.Fclose (masterfd);
RETURN -1
END;
FOR i := 0 TO 3 DO
old[i] := MagicDOS.Fdup (i-1); (* Kanle -1..2 duplizieren *)
END;
FOR i := 0 TO 3 DO
v.bool := MagicDOS.Fforce(i-1,slavefd); (* Kanle -1 .. 2 umsetzen *)
END;
pid := Mintbind.Pfork(); (* Prozess verdoppeln *)
IF (pid = 0) THEN (* Der neue Kindprozess... *)
FOR i := 0 TO 3 DO
v.int := MagicDOS.Fclose(old[i]); (* Kopien schlieen *)
END;
v.int := MagicDOS.Pexec(200, name, cmdline, env); (* berlagern *)
MagicDOS.Pterm(-1); (* Kommt hier nur an, wenn *)
(* Pexec nicht klappte *)
END; (* IF *)
FOR i := 0 TO 3 DO
v.bool := MagicDOS.Fforce(i-1,old[i]); (* Kanle -1 .. 2 zurcksetzen *)
v.int := MagicDOS.Fclose(old[i]); (* Kopien schlieen *)
END;
v.int := MagicDOS.Fclose(slavefd);
pipe := masterfd;
RETURN pid;
END ExecPipe;
(*
* Liest von einer Pipe, sofern dort Daten vorhanden sind.
* Liefert Null, wenn keine Daten da waren, -1 wenn der
* Pipe-Prozess bendet wurde und einen positiven Wert, wenn
* Zeichen gelesen wurden.
*)
VAR rus : ARRAY [0..7] OF LONGINT;
PROCEDURE ReadPipe (pid, pipe : INTEGER; VAR buf : ARRAY OF CHAR;
VAR retCode : INTEGER): LONGINT;
VAR size : LONGINT;
cSize : LONGCARD;
lc : MagicSys.lBITSET;
BEGIN
size := Mintbind.Finstat (pipe);
IF (size > 0) THEN
IF size > LONGINT(LONG(HIGH (buf))) THEN
size := HIGH(buf);
END;
cSize := size;
MagicDOS.Fread(pipe,cSize,ADR(buf));
size := cSize;
END;
IF (size <= 0) (* Testen ob Prozess gestorben ist *)
& (Mintbind.Pkill(pid,0) < 0)
THEN
lc := MagicSys.lBITSET{};
v.int := Mintbind.Fselect(150, lc, lc, NIL); (* Meist kommt trotzdem noch etwas *)
(* in der Pipe an, also kurz warten *)
IF Mintbind.Finstat(pipe) = 0
THEN
v.int := MagicDOS.Fclose(pipe); (* Pipe schlieen, wenn nichts kam *)
END;
v.lint := Mintbind.Pwait3(1,rus); (* Zombie entfernen *)
IF v.lint # LONG(MagicDOS.EFilNF)
THEN
retCode := CAST (INTEGER, v.lint); (* Einfach abschneiden *)
ELSE
retCode := 0;
END;
END;
RETURN size;
END ReadPipe;
(*
* Liefert 1 wenn MiNT installiert ist, sonst 0.
*)
PROCEDURE IsMiNT() : BOOLEAN;
VAR val : LONGCARD;
BEGIN
RETURN MagicCookie.FindCookie ('MiNT', val)
END IsMiNT;
(*
VAR pipe, pid : INTEGER;
str : ARRAY [0..152] OF CHAR;
size : LONGINT;
BEGIN
IF ~IsMiNT() THEN
WriteString ("Leider kein MiNT installiert...");
WriteLn;
RETURN
END;
v.int := ExecDevNull ("c:\usr\mint\ls.ttp","","");
pid := ExecPipe ("c:\usr\mint\ps.ttp",2c+"-l","",pipe);
IF pid > 0
THEN
REPEAT
size := ReadPipe (pid, pipe, str);
IF size > 0 THEN
str[SHORT(size)] := 0c;
WriteString (str);
END;
UNTIL size < 0;
END;
v.lint:=Mintbind.Pwait3(0,rus); (* Warten bis Kind (/dev/null) beendet *)
*)
END MintUtil.